diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,14 @@
 o'clock uses [PVP Versioning][1].
 The change log is available [on GitHub][2].
 
+1.2.1.1
+=====
+
+* [#125](https://github.com/serokell/o-clock/pull/125):
+  + Remove `ghc-prim` dependency.
+  + Remove old artifacts of GHC<8.6 support.
+  + Make `base` constraints stricter.
+
 1.2.1
 =====
 
diff --git a/README.lhs b/README.lhs
--- a/README.lhs
+++ b/README.lhs
@@ -80,9 +80,7 @@
 ```haskell
 {-# LANGUAGE CPP              #-}
 {-# LANGUAGE DataKinds        #-}
-#if ( __GLASGOW_HASKELL__ >= 806 )
 {-# LANGUAGE NoStarIsType     #-}
-#endif
 {-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE TypeFamilies     #-}
 {-# LANGUAGE TypeOperators    #-}
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -80,9 +80,7 @@
 ```haskell
 {-# LANGUAGE CPP              #-}
 {-# LANGUAGE DataKinds        #-}
-#if ( __GLASGOW_HASKELL__ >= 806 )
 {-# LANGUAGE NoStarIsType     #-}
-#endif
 {-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE TypeFamilies     #-}
 {-# LANGUAGE TypeOperators    #-}
diff --git a/o-clock.cabal b/o-clock.cabal
--- a/o-clock.cabal
+++ b/o-clock.cabal
@@ -1,9 +1,10 @@
+cabal-version: 2.2
 -- SPDX-FileCopyrightText: 2020-2021 Serokell <https://serokell.io>
 --
 -- SPDX-License-Identifier: MPL-2.0
 
 name:                o-clock
-version:             1.2.1
+version:             1.2.1.1
 synopsis:            Type-safe time library.
 description:         See README.md for details.
 homepage:            https://github.com/serokell/o-clock
@@ -19,46 +20,50 @@
 extra-doc-files:     CHANGELOG.md
                    , README.md
                    , README.lhs
-cabal-version:       2.0
 tested-with:         GHC == 8.6.5
                    , GHC == 8.8.3
                    , GHC == 8.10.4
+                   , GHC == 9.0.1
+                   , GHC == 9.2.1
 
 source-repository head
   type:     git
   location: https://github.com/serokell/o-clock
 
+common common-options
+  build-depends:
+      base >=4.12 && <4.17
+  ghc-options: -Wall
+  default-language: Haskell2010
+
 library
+  import:              common-options
   hs-source-dirs:      src
   exposed-modules:     Time
                          Time.Rational
                          Time.Series
                          Time.Timestamp
                          Time.Units
-  ghc-options:         -Wall
-  build-depends:       base         >= 4.9  && < 5
-                     , ghc-prim     >= 0.5 && < 0.7
-  default-language:    Haskell2010
   default-extensions:  OverloadedStrings
                        RecordWildCards
                        ScopedTypeVariables
                        TypeApplications
                        TypeFamilies
   if flag(aeson)
-    build-depends:     aeson    >= 1.2.4 && < 1.6
+    build-depends:     aeson    >= 1.2.4 && < 2.1
                      , text
     cpp-options:       -DHAS_aeson
 
 executable play-o-clock
+  import:              common-options
   main-is:             Playground.hs
   build-depends:       o-clock
-                     , base     >= 4.9  && < 5
   hs-source-dirs:      examples
-  default-language:    Haskell2010
-  ghc-options:         -threaded -Wall
+  ghc-options:         -threaded
                        -fno-warn-orphans
 
 test-suite o-clock-test
+  import:              common-options
   type:                exitcode-stdio-1.0
   hs-source-dirs:      test
   main-is:             Spec.hs
@@ -68,21 +73,20 @@
                        Test.Time.TypeSpec
                        Test.Time.Units
 
-  build-depends:       base            >= 4.9  && < 5
-                     , o-clock
-                     , hedgehog       >= 0.6 && < 1.1
+  build-depends:       o-clock
+                     , hedgehog       >= 0.6 && < 1.2
                      , hspec-expectations ^>= 0.8
                      , tasty          >= 0.12 && < 1.5
                      , tasty-hedgehog >= 0.1 && < 1.2
                      , tasty-hunit-compat ^>= 0.2
                      , type-spec      >= 0.3.0.1 && < 0.5
 
-  ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
-  default-language:    Haskell2010
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
   default-extensions:  OverloadedStrings
                        RecordWildCards
 
 test-suite o-clock-doctest
+  import:              common-options
   if os(windows)
      buildable: False
 
@@ -91,13 +95,12 @@
   main-is:             Doctest.hs
 
   build-tool-depends:  doctest:doctest
-  build-depends:       base    >= 4.10 && < 5
-                     , doctest >= 0.16 && < 0.19
+  build-depends:       doctest >= 0.16 && < 0.21
                      , Glob    >= 0.9 && < 0.11
-  ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
-  default-language:    Haskell2010
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 
 test-suite readme-test
+  import:              common-options
   if os(windows)
      buildable: False
 
@@ -105,25 +108,23 @@
   main-is:             README.lhs
 
   build-tool-depends:  markdown-unlit:markdown-unlit
-  build-depends:       base            >= 4.10  && < 5
-                     , o-clock
+  build-depends:       o-clock
                      , markdown-unlit ^>= 0.5
-  ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N -pgmL markdown-unlit
-  default-language:    Haskell2010
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -pgmL markdown-unlit
 
 benchmark o-clock-benchmark
+  import:              common-options
   type:                exitcode-stdio-1.0
-  default-language:    Haskell2010
-  ghc-options:         -Wall -O2 -threaded -rtsopts -with-rtsopts=-N
+  ghc-options:         -O2 -threaded -rtsopts -with-rtsopts=-N
   hs-source-dirs:      benchmark
   main-is:             Main.hs
-  build-depends:       base       >= 4.8   && < 5
-                     , deepseq    >= 1.4
+  build-depends:       deepseq    >= 1.4
                      , o-clock
                      , gauge      >= 0.2.1 && < 1
                      , tiempo     >= 0.0.1.1
                      , time-units == 1.0.0
-  if !flag(bench-buildable)
+  -- ghc 9.2 is not supported by gauge (due to basement)
+  if !flag(bench-buildable) || impl(ghc >= 9.2)
     buildable:         False
 
   default-extensions:  OverloadedStrings
diff --git a/src/Time/Rational.hs b/src/Time/Rational.hs
--- a/src/Time/Rational.hs
+++ b/src/Time/Rational.hs
@@ -3,15 +3,13 @@
 -- SPDX-License-Identifier: MPL-2.0
 
 {-# LANGUAGE AllowAmbiguousTypes  #-}
-{-# LANGUAGE ConstraintKinds      #-}
 {-# LANGUAGE CPP                  #-}
-{-# LANGUAGE TypeInType           #-}
+{-# LANGUAGE ConstraintKinds      #-}
 {-# LANGUAGE FlexibleContexts     #-}
 {-# LANGUAGE FlexibleInstances    #-}
-#if ( __GLASGOW_HASKELL__ >= 806 )
-{-# LANGUAGE NoStarIsType               #-}
-#endif
+{-# LANGUAGE NoStarIsType         #-}
 {-# LANGUAGE Rank2Types           #-}
+{-# LANGUAGE TypeInType           #-}
 {-# LANGUAGE TypeOperators        #-}
 {-# LANGUAGE UndecidableInstances #-}
 
@@ -42,7 +40,7 @@
 import Data.Proxy (Proxy (..))
 import GHC.Natural (Natural)
 import GHC.Real (Ratio ((:%)))
-import GHC.TypeNats (Div, Mod, type (<=?), KnownNat, Nat, natVal)
+import GHC.TypeNats (Div, KnownNat, Mod, Nat, natVal, type (<=?))
 import qualified GHC.TypeNats
 import Unsafe.Coerce (unsafeCoerce)
 
@@ -92,6 +90,11 @@
     a % b = Normalize (a :% b)
 infixl 7 %
 
+-- Note about usage of CPP for doctests:
+-- @:%@ is a synonym for @'::%@. GHC older than 9.2 does not expand
+-- type synonyms when @:kind!@ is used in REPL, so we get the short synonym.
+-- Starting from 9.2 type synonyms are expanded, so we get @'::%@.
+
 {- | Division of type-level rationals.
 
 If there are 'Rat' with 'Nat's @a@ and @b@ and another
@@ -101,51 +104,103 @@
  \]
 
 __Example:__
-
+-}
+#if ( __GLASGOW_HASKELL__ >= 902 )
+{- |
 >>> :kind! DivRat (9 % 11) (9 % 11)
 DivRat (9 % 11) (9 % 11) :: Rat
+= 1 '::% 1
+-}
+#else
+{- |
+>>> :kind! DivRat (9 % 11) (9 % 11)
+DivRat (9 % 11) (9 % 11) :: Rat
 = 1 :% 1
 -}
+#endif
 type family DivRat (m :: Rat) (n :: Rat) :: Rat where
     DivRat (a :% b) (c :% d) = (a * d) % (b * c)
 
 {- | Multiplication for type-level rationals.
 
 __Example:__
-
+-}
+#if ( __GLASGOW_HASKELL__ >= 902 )
+{- |
 >>> :kind!  MulRat (2 % 3) (9 % 11)
 MulRat (2 % 3) (9 % 11) :: Rat
+= 6 '::% 11
+-}
+#else
+{- |
+>>> :kind!  MulRat (2 % 3) (9 % 11)
+MulRat (2 % 3) (9 % 11) :: Rat
 = 6 :% 11
 -}
+#endif
 type family MulRat (m :: Rat) (n :: Rat) :: Rat where
     MulRat (a :% b) (c :% d) = (a * c) % (b * d)
 
 {- | Multiplication of type-level natural with rational.
 
 __Example:__
+-}
+#if ( __GLASGOW_HASKELL__ >= 902 )
+{- |
 
 >>> :kind!  MulNatRat 2 (9 % 11)
 MulNatRat 2 (9 % 11) :: Rat
+= 18 '::% 11
+-}
+#else
+{- |
+
+>>> :kind!  MulNatRat 2 (9 % 11)
+MulNatRat 2 (9 % 11) :: Rat
 = 18 :% 11
 -}
+#endif
 type family MulNatRat (n :: Nat) (r :: Rat) :: Rat where
     MulNatRat x (a :% b) = (x * a) % b
 
 {- | Division of type-level rational and natural.
 
 __Example:__
+-}
+#if ( __GLASGOW_HASKELL__ >= 902 )
+{- |
 
 >>> :kind!  DivRatNat (9 % 11) 2
 DivRatNat (9 % 11) 2 :: Rat
+= 9 '::% 22
+-}
+#else
+{- |
+
+>>> :kind!  DivRatNat (9 % 11) 2
+DivRatNat (9 % 11) 2 :: Rat
 = 9 :% 22
 -}
+#endif
 type family DivRatNat (r :: Rat) (n :: Nat) :: Rat where
     DivRatNat (a :% b) x = a % (b * x)
 
 {- | Greatest common divisor for type-level naturals.
 
 __Example:__
+-}
+#if ( __GLASGOW_HASKELL__ >= 902 )
+{- |
+>>> :kind! Gcd 9 11
+Gcd 9 11 :: Natural
+= 1
 
+>>> :kind! Gcd 9 12
+Gcd 9 12 :: Natural
+= 3
+-}
+#else
+{- |
 >>> :kind! Gcd 9 11
 Gcd 9 11 :: Nat
 = 1
@@ -154,6 +209,7 @@
 Gcd 9 12 :: Nat
 = 3
 -}
+#endif
 type family Gcd (m :: Nat) (n :: Nat) :: Nat where
     Gcd a 0 = a
     Gcd a b = Gcd b (a `Mod` b)
@@ -161,7 +217,19 @@
 {- | Normalization of type-level rational.
 
 __Example:__
+-}
+#if ( __GLASGOW_HASKELL__ >= 902 )
+{- |
+>>> :kind! Normalize (9 % 11)
+Normalize (9 % 11) :: Rat
+= 9 '::% 11
 
+>>> :kind! Normalize (9 % 12)
+Normalize (9 % 12) :: Rat
+= 3 '::% 4
+-}
+#else
+{- |
 >>> :kind! Normalize (9 % 11)
 Normalize (9 % 11) :: Rat
 = 9 :% 11
@@ -170,6 +238,8 @@
 Normalize (9 % 12) :: Rat
 = 3 :% 4
 -}
+#endif
+
 type family Normalize (r :: Rat) :: Rat  where
     Normalize (a :% b) = (a `Div` Gcd a b) :% (b `Div` Gcd a b)
 
diff --git a/src/Time/Timestamp.hs b/src/Time/Timestamp.hs
--- a/src/Time/Timestamp.hs
+++ b/src/Time/Timestamp.hs
@@ -27,7 +27,7 @@
 
        ) where
 
-import GHC.Prim (coerce)
+import Data.Coerce (coerce)
 
 import Time.Rational (KnownDivRat, KnownRat, Rat, RatioNat)
 import Time.Units (Second, Time (..), sec, toUnit)
diff --git a/src/Time/Units.hs b/src/Time/Units.hs
--- a/src/Time/Units.hs
+++ b/src/Time/Units.hs
@@ -11,9 +11,7 @@
 {-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE InstanceSigs               #-}
-#if ( __GLASGOW_HASKELL__ >= 806 )
 {-# LANGUAGE NoStarIsType               #-}
-#endif
 {-# LANGUAGE TypeOperators              #-}
 {-# LANGUAGE UndecidableInstances       #-}
 
@@ -69,12 +67,12 @@
 import Control.Monad (unless)
 import Control.Monad.IO.Class (MonadIO, liftIO)
 import Data.Char (isDigit, isLetter)
+import Data.Coerce (coerce)
 import Data.Foldable (foldl')
 import Data.Proxy (Proxy (..))
 import Data.Semigroup (Semigroup (..))
 import GHC.Generics (Generic)
 import GHC.Natural (Natural)
-import GHC.Prim (coerce)
 import GHC.Read (Read (readPrec))
 import GHC.Real (denominator, numerator, (%))
 import GHC.TypeLits (KnownSymbol, Symbol, symbolVal)
